﻿/*
Name:		    Silverlight OOB Extension
Description:	This Extensions helps the OOB functions.
O/S: 		    For Silverlight 3 API
Date:		    30.05.2009
Author:		    Gregor Biswanger (E-Mail: gregor.biswanger@web-enliven.de - Blog:www.dotnet-blog.net)
Company:		Web-Enliven

Notes:		    This Source-Code is Open-Source with Mozilla Public License 1.1 (MPL).
*/

using System.IO;
using System.IO.IsolatedStorage;
using System.Runtime.Serialization;

namespace Silverlight.OOB.Extension
{
    /// <summary>
    /// This component can Serializable the Data to isolated Storige.
    /// So you can use this for Caching files for offline state. 
    /// </summary>
    /// <typeparam name="T">Here comes the Object-type was goes to Offline Cache.</typeparam>
    public class OfflineCaching<T>
    {
        /// <summary>
        /// The filename from Caching-Tempfile
        /// </summary>
        private readonly string CachingFileName = typeof( T ).Name.Trim();

        /// <summary>
        /// Determines whether [is caching session exists].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if [is caching session exists]; otherwise, <c>false</c>.
        /// </returns>
        public bool IsCachingSessionExists()
        {
            using (var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication())
                return isolatedStorageFile.FileExists(CachingFileName);
        }

        /// <summary>
        /// Casts the specified data to caching offline.
        /// </summary>
        /// <param name="data">The data to caching offline.</param>
        /// <returns></returns>
        public T Cast(T data)
        {
            SaveData(data);
            return LoadData();
        }

        /// <summary>
        /// Updates the exists data in offline cache.
        /// </summary>
        /// <param name="data">The new data to caching offline.</param>
        public void UpdateData(T data)
        {
            SaveData(data);
        }

        /// <summary>
        /// Gets the data from offline caching.
        /// </summary>
        /// <returns></returns>
        public T GetDataFromOfflineCaching()
        {
            return LoadData();
        }

        /// <summary>
        /// Clears the offline cache.
        /// </summary>
        public void ClearCache()
        {
            DeleteData();
        }

        /// <summary>
        /// Saves the data to isolated Storage.
        /// </summary>
        /// <param name="data">The data to caching offline.</param>
        private void SaveData( T data )
        {
            using( var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication() )
            {
                ClearCache();

                using( var fileStream = isolatedStorageFile.CreateFile( CachingFileName ) )
                {
                    DataContractSerializer serializer = new DataContractSerializer( typeof( T ) );
                    serializer.WriteObject( fileStream, data );
                }
            }
        }

        /// <summary>
        /// Deletes the data from isolated Storage.
        /// </summary>
        private void DeleteData()
        {
            using( var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication() )
            {
                if(IsCachingSessionExists())
                    isolatedStorageFile.DeleteFile( CachingFileName );
            }
        }

        /// <summary>
        /// Loads the offline data from isolated Storage.
        /// </summary>
        /// <returns>The data from offline caching.</returns>
        private T LoadData()
        {
            T modelData = default( T );

            using( var isolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication() )
            {
                if( IsCachingSessionExists() )
                {
                    using( var fileStream = isolatedStorageFile.OpenFile( CachingFileName, FileMode.Open ) )
                    {
                        DataContractSerializer serializer = new DataContractSerializer( typeof( T ) );
                        modelData = ( T ) serializer.ReadObject( fileStream );
                    }
                }
            }

            return modelData;
        }
    }
}